﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using Confucius.dao;
using System.Runtime.CompilerServices;
using Confucius.daoImpl;
using Confucius.utils;
using DBContent.Model;
using System.IO.IsolatedStorage;

namespace Confucius.entity
{
    /// <summary>
    /// Author:Liangchuan Gu
    /// date:2012-04-08
    /// </summary>
    public class GameRuleManager
    {
        private Dictionary<ObjectTriggerIndex, List<String>> objectTriggerIDsTable;
        private Dictionary<String, Trigger> triggerTable;
        private static GameRuleManager manager;
        private static GameRuleDAO gameRuleDAO;
        private String gameID;
        private static int CACHE_SIZE = 20;

        private GameRuleManager(String gameID) 
        {
            objectTriggerIDsTable = new Dictionary<ObjectTriggerIndex, List<String>>();
            triggerTable = new Dictionary<String, Trigger>();
            this.gameID = gameID;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public static GameRuleManager getInstance(String gameID)
        {
            if (manager == null)
            {
                manager = new GameRuleManager(gameID);
            }
            
            gameRuleDAO = new GameRuleDAOImpl();
            return manager;
        }

        public Boolean gameRuleCheck(String gameObjectID, String gameObjectAction) 
        {
            if (!objectTriggerIDsTable.ContainsKey(new ObjectTriggerIndex(gameObjectID,
                    gameObjectAction)))
            {
                objectTriggerIDsTable.Add(new ObjectTriggerIndex(gameObjectID,
                    gameObjectAction), gameRuleDAO
                    .getGameObjectAssociatedTriggerIDs(gameID,
                            gameObjectAction, gameObjectID));
            }

            List<String> triggerIDs = objectTriggerIDsTable[new ObjectTriggerIndex(gameObjectID, gameObjectAction)];

            foreach (String triggerID in triggerIDs)
            {
                if (!triggerTable.ContainsKey(triggerID))
                {
                    triggerTable.Add(triggerID,
                        gameRuleDAO.loadTrigger(triggerID, gameID));
                }
                Trigger trigger = triggerTable[triggerID];
                List<Condition> conditions = trigger.Conditions;
                int satisfiedCondition = 0;
                foreach (Condition condition in conditions)
                {
                    if (condition.ConditionType.Equals(Condition.COMPLETE_QUEST_CONDITION))
                    {
                        DBQuest dbQuest = new DBQuest();
                        dbQuest.QuestID = condition.ParamX;
                        String questStatus = ConfuciusDBHelper.getQuestStatus(dbQuest);
                        if (questStatus != null)
                        {
                            if (questStatus.Equals(Quest.COMPLETE_STATUS))
                            {
                                satisfiedCondition++;
                            }
                        }
                    }
                    else if (condition.ConditionType.Equals(Condition.START_QUEST_CONDITION))
                    {
                        DBQuest dbQuest = new DBQuest();
                        dbQuest.QuestID = condition.ParamX;
                        String questStatus = ConfuciusDBHelper.getQuestStatus(dbQuest);
                        if (questStatus != null)
                        {
                            if (questStatus.Equals(Quest.START_STATUS))
                            {
                                satisfiedCondition++;
                            }
                        }
                    }
                    else if (condition.ConditionType.Equals(Condition.FINISH_CHAT_CONDITION))
                    {
                        DBNpc dbNpc = new DBNpc();
                        dbNpc.NpcID = condition.ParamX;
                        String npcStatus = ConfuciusDBHelper.getNpcStatus(dbNpc);
                        if (npcStatus != null)
                        {
                            if (npcStatus.Equals(NPC.END_CHAT))
                            {
                                satisfiedCondition++;
                            }
                        }
                    }
                    else if (condition.ConditionType.Equals(Condition.GREET_CONDITION))
                    {
                        satisfiedCondition++;
                    }
                    else if (condition.ConditionType.Equals(Condition.PICK_ITEM_CONDITION))
                    {
                        DBItem dbItem = new DBItem();
                        dbItem.ItemID = condition.ParamX;
                        String itemStatus = ConfuciusDBHelper.getItemStatus(dbItem);
                        if (itemStatus != null)
                        {
                            if (itemStatus.Equals(Item.PICKED))
                            {
                                satisfiedCondition++;
                            }
                        }
                    }
                }
                if (satisfiedCondition == conditions.Count)
                {
                    fireTrigger(trigger);
                }
            }
            return true;
        }

        private void fireTrigger(Trigger trigger) 
        {
            gameRuleDAO.updateTriggerStatus(trigger.TriggerID,Trigger.TRIGGER_STATUS);

            if (trigger.ActionType.Equals(Trigger.BECOME_CHATTABLE_ACTION))
            {
                NPCDAO npcDAO = new NPCDAOImpl();
                npcDAO.updateNPCStatus(trigger.ActionObjectID, NPC.CHATTABLE);
            }
            else if (trigger.ActionType.Equals(Trigger.BECOME_PICKABLE_ACTION))
            {
                ItemDAO itemDAO = new ItemDAOImpl();
                itemDAO.updateItemStatus(trigger.ActionObjectID, Item.PICKABLE);
            }
            else if (trigger.ActionType.Equals(Trigger.COMPLETE_QUEST_ACTION))
            {
                QuestDAO questDAO = new QuestDAOImpl();
                questDAO.updateQuestStatus(trigger.ActionObjectID,
                        Quest.COMPLETE_STATUS);

                int finishHighestOrder;
                if (IsolatedStorageSettings.ApplicationSettings.Contains(Constants.HIGHEST_AVAILABLE_QUESTS))
                {
                    finishHighestOrder = (int)IsolatedStorageSettings.ApplicationSettings[Constants.HIGHEST_AVAILABLE_QUESTS];
                }
                else 
                {
                    finishHighestOrder = 0;
                }
                IsolatedStorageSettings.ApplicationSettings.Remove(Constants.HIGHEST_AVAILABLE_QUESTS);
                IsolatedStorageSettings.ApplicationSettings.Add(Constants.HIGHEST_AVAILABLE_QUESTS, (finishHighestOrder + 1));
                IsolatedStorageSettings.ApplicationSettings.Save();

                MessageBox.Show(trigger.TriggerText, "Trigger: " + trigger.TriggerID, MessageBoxButton.OK);

                // trigger a quest complete condition
                this.gameRuleCheck(trigger.ActionObjectID,
                        Condition.COMPLETE_QUEST_CONDITION);
            }
        }
    }
}
